﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ItemComponent;

namespace Battle
{
    public class BulletBase : MonoBehaviour, IBullet
    {
        public enum EM_BulletType
        {
            Normal,
            Catapult,
            Penetrate,
            AOE,
        }

        protected const float DefaultLifeTime = 5f;

        public Vector3 Pos => transform.position;
        public ST_BulletData BulletData { get; private set; }
        protected IBulletHitHandler hitHandler;
        private float _fBornTime;

        [SerializeField,ReadOnly]
        protected int nCatapultNum, nPenetrateCount;
        /// <summary>
        /// 弹射
        /// </summary>
        public int CanCatapultNum => nCatapultNum;
        /// <summary>
        /// 穿透
        /// </summary>
        public int CanPenetrateCount => nPenetrateCount;

        [SerializeField,ReadOnly]
        protected EM_BulletType eM_BulletType;
        public EM_BulletType BulletType => eM_BulletType;

        protected Move_Normal moveComponent;
        protected IEnemyTargetGetter targetGetter;

        public virtual void InitBulletData(ST_BulletData bulletData, IBulletHitHandler hitHandler, IEnemyTargetGetter targetGetter)
        {
            //生命周期
            _fBornTime = Time.time;

            if (bulletData.fLifeTime <= 0) bulletData.fLifeTime = DefaultLifeTime;

            this.BulletData = bulletData;
            this.hitHandler = hitHandler;
            this.targetGetter = targetGetter;

            //计算子弹类型
            if (bulletData.nCatapultCount == 0 && bulletData.nPenetrateCount == 0)
                eM_BulletType = EM_BulletType.Normal;
            else
                eM_BulletType = bulletData.nCatapultCount > bulletData.nPenetrateCount ? EM_BulletType.Catapult : EM_BulletType.Penetrate;

            //弹射，穿透
            nCatapultNum = bulletData.nCatapultCount;
            nPenetrateCount = bulletData.nPenetrateCount;

            transform.position = bulletData.vBornPos;

            InitMoveComonent();
        }

        protected virtual void InitMoveComonent()
        {
            if (moveComponent == null)
            {
                moveComponent = Move_Normal.AddComponent(gameObject, BulletData.vTargetPos, BulletData.fSpeed);
            }
            else
                moveComponent.InitMoveData(BulletData.vTargetPos, BulletData.fSpeed);
        }

        protected virtual void Update()
        {
            if (Time.time - _fBornTime > BulletData.fLifeTime)
            {
                DestorySelf();
            }
        }

        private void OnTriggerEnter2D(Collider2D collision)
        {
            ICanHitObj target = collision.GetComponentInParent<ICanHitObj>();

            if (target != null)
                OnHitObj(target);
        }

        protected virtual void SetTarget(ICanHitObj canHitObj)
        {
            if (canHitObj == null)
                DestorySelf();
            else
                moveComponent.InitMoveData(canHitObj.Pos, BulletData.fSpeed);
        }

        protected virtual void OnHitObj(ICanHitObj target)
        {
            int repelNum = (int)(BulletData.nRepelNum * BulletData.fSpeed);

            if (hitHandler != null)
            {
                if (hitHandler.OnHit(this, target))
                    DestorySelf();
                else
                    AfterHitObj(target);
            }
            else
            {
                target?.OnHit(new ST_HitActionData(BulletData.nDmg, repelNum, moveComponent?.MoveDir ?? default));
                AfterHitObj(target);
            }
        }
        protected virtual void AfterHitObj(ICanHitObj target)
        {
            if (CheckNeedDestory())
            {
                DestorySelf();
            }
            else
            {
                switch (eM_BulletType)
                {
                    //case EM_BulletType.Normal:
                    //    break;
                    case EM_BulletType.Catapult:
                        //弹射
                        nCatapultNum--;
                        SetTarget(targetGetter.GetTarget(transform.position, new ICanHitObj[] { target }));
                        break;
                    case EM_BulletType.Penetrate:
                        //穿透
                        nPenetrateCount--;
                        break;
                }

            }
        }

        public virtual bool CheckNeedDestory()
        {
            bool needDestory=true;
            switch (eM_BulletType)
            {
                case EM_BulletType.Normal:
                    //needDestory = true;
                    break;
                case EM_BulletType.Catapult:
                    needDestory = nCatapultNum <= 0;
                    break;
                case EM_BulletType.Penetrate:
                    needDestory = nPenetrateCount <= 0;
                    break;
            }
            return needDestory;
        }
        public virtual void DestorySelf()
        {
            //TODO 内存池
            Destroy(gameObject);
        }

    }
}